#Algorithm for hunger games.
#There are three different strategies for three different stages of the game.
#In round 1, the strategy is simply to hunt with 50% of opponents, chosen randomly.
#This establishes a moderate self-reputation which can be modified easily depending
#on how the game progresses.
#Thereafter, a mid-game strategy is employed, where a target reputation is determined,
#in the upper percentile of the population, but not at the top.
#This is to avoid over-spending food whilst attempting to establish reputation.
#However, if the target reputation is too low, such that due to a low percentile ranking
#of reputation, opponents are unlikely to decide to hunt, a higher target reputation
#would be chosen to meet the required percentile.
#The endgame strategy is triggered in two ways: when current_food has depleted to
#a dangerously low level with respect to the number of opponents, or when the number
#of players in the game has fallen to below half of the initial population.
#The endgame strategy is simply to slack continuously, with the idea of outlasting
#remaining players in the game.
#At the endgame, if current_food is low, food matters more than reputation, so slacking is justified.
#Once half the population has died, reputation is likely to be well established, hence slacking
#is expected to be profitable.


import numpy

popsize = []

def hunt_choices(round_number, current_food, current_reputation, m,  player_reputations):
    popsize.append(len(player_reputations))
    
    if round_number == 1: #Round 1: 50% random chance of hunting.
        hunt_decisions  = []
        for i in player_reputations:
            y = numpy.random.uniform()
            if y < 0.5:
                hunt_decisions.append('h')
            else:
                hunt_decisions.append('s')
                
    elif current_food < 50*popsize[-1] or popsize[-1] <= 0.5*popsize[0]: #endgame
        hunt_decisions = ['s' for x in player_reputations] #endgame: slack always

    else: #midgame
        hunt_decisions = []
        decrep = sorted(player_reputations, reverse = True) #decreasing reputation
        tenthreshold = int(0.1*popsize[-1])
        if tenthreshold != 0:
            toptenpercent = decrep[0:tenthreshold]
        else:
            toptenpercent = decrep[0]
        targetrep = numpy.mean([numpy.mean(toptenpercent),numpy.mean(decrep)])
        #targetrep is mean of total mean rep, and top 10%'s mean rep.
        #compare targetrep with (1-targetrep)th percentile rep. Select higher rep.
        #position of (1-targetrep)th percentile:
        comppos = int(targetrep*popsize[-1]) #compare position
        if decrep[comppos] > targetrep:
            targetrep = decrep[comppos]
        #fill in hunt_decisions
        
        counter = 0 #counter needs to reach targetrep*popsize[-1]
        if targetrep > 0.4: #don't exploit
            #expect to hunt with players only with rep above repthreshold.
            repthreshold = decrep[int(targetrep*popsize[-1])]
            for i in player_reputations:
                if i >= repthreshold and counter < targetrep*popsize[-1]:
                    hunt_decisions.append('h')
                    counter += 1
                else:
                    hunt_decisions.append('s')
        #intend to exploit (slack) with top 5% of reputations, if targetrep>0.4, and thereafter hunt with remaining highest reputations.
        #this is to reduce 'income disparity', ensuring players with the best reputations don't become too high on food.
        else: #exploit top 5%
            highrepthreshold = decrep[int(0.05*popsize[-1])]
            lowrepthreshold = decrep[int((0.05+targetrep)*popsize[-1])]
            for i in player_reputations:
                if i > highrepthreshold: #group to exploit
                    hunt_decisions.append('s')
                elif lowrepthreshold < i <= highrepthreshold and counter < targetrep*popsize[-1]: #group to hunt with
                    hunt_decisions.append('h')
                    counter += 1
                else:#slack with remaining players with low rep.
                    hunt_decisions.append('s')

    return hunt_decisions;


def hunt_outcomes(food_earnings):
    pass


def round_end(award, m, number_hunters):
    pass
